package org.example.rzfx.netty;

import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.example.rzfx.entity.Log;
import org.example.rzfx.service.CollectMonitorService;
import org.example.rzfx.service.LogService;
import org.example.rzfx.util.LogParseUtil;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * Netty日志处理器
 */
@Component
@Slf4j
@ChannelHandler.Sharable
public class NettyLogHandler extends SimpleChannelInboundHandler<String> {
    
    @Resource
    private LogService logService;
    
    @Resource
    private CollectMonitorService collectMonitorService;
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        try {
            // 处理接收到的日志消息
            processLogMessage(msg);
        } catch (Exception e) {
            log.error("处理日志消息失败: " + msg, e);
        }
    }
    
    /**
     * 处理日志消息
     */
    private void processLogMessage(String msg) {
        try {
            // 尝试解析为JSON格式
            JSONObject json = JSON.parseObject(msg);
            
            Log logEntity = new Log();
            logEntity.setContent(msg);
            
            // 从JSON中提取字段
            if (json.containsKey("timestamp")) {
                try {
                    String timestampStr = json.getString("timestamp");
                    LocalDateTime timestamp = LocalDateTime.parse(timestampStr,
                        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    logEntity.setTimestamp(timestamp);
                } catch (Exception e) {
                    logEntity.setTimestamp(LocalDateTime.now());
                }
            } else {
                logEntity.setTimestamp(LocalDateTime.now());
            }
            
            // 日志级别
            if (json.containsKey("level")) {
                logEntity.setLogLevel(json.getString("level"));
            } else {
                logEntity.setLogLevel(LogParseUtil.extractLogLevel(msg));
            }
            
            // 系统类型
            if (json.containsKey("system")) {
                logEntity.setSystemType(json.getString("system"));
            } else {
                logEntity.setSystemType("NETWORK");
            }
            
            // 采集源ID（网络日志默认使用4号采集源）
            if (json.containsKey("sourceId")) {
                logEntity.setSourceId(json.getLong("sourceId"));
            } else {
                logEntity.setSourceId(4L);
            }
            
            // 存储字段
            logEntity.setFields(msg);
            
            // 生成唯一hash
            String uniqueHash = MD5.create().digestHex(msg + logEntity.getTimestamp().toString());
            logEntity.setUniqueHash(uniqueHash);
            
            // 保存日志
            logService.saveLog(logEntity);
            
            // 更新监控数据
            collectMonitorService.incrementSuccess(logEntity.getSourceId());
            
            log.debug("成功接收网络日志: {}", msg);
            
        } catch (Exception e) {
            // 如果不是JSON格式，按普通文本处理
            processPlainTextLog(msg);
        }
    }
    
    /**
     * 处理普通文本日志
     */
    private void processPlainTextLog(String msg) {
        Log logEntity = new Log();
        logEntity.setSourceId(4L); // 网络日志默认采集源
        logEntity.setContent(msg);
        logEntity.setTimestamp(LocalDateTime.now());
        logEntity.setLogLevel(LogParseUtil.extractLogLevel(msg));
        logEntity.setSystemType("NETWORK");
        
        String uniqueHash = MD5.create().digestHex(msg + LocalDateTime.now().toString());
        logEntity.setUniqueHash(uniqueHash);
        
        logService.saveLog(logEntity);
        collectMonitorService.incrementSuccess(4L);
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("客户端连接: {}", ctx.channel().remoteAddress());
    }
    
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("客户端断开: {}", ctx.channel().remoteAddress());
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("处理异常", cause);
        ctx.close();
    }
}

